<?php

class DatabasePDO
{
	private $host	= DB_HOST;
	private $user	= DB_USER;
	private $pass	= DB_PASS;
	private $dbname	= DB_NAME;
	
	private $dbh;
	private $error;
	private $stmt;
	
	public $count 		= array();
	public $insert_id 	= array();
	
	public function __construct()
	{
		// Set the initial connection
		$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
		
		// Set options
		$options = array(
			PDO::ATTR_PERSISTENT	=> true,
			PDO::ATTR_ERRMODE		=> PDO::ERRMODE_EXCEPTION
		);
		
		// Create a new PDO instance
		try
		{
			$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
		}
		catch (PDOException $e)
		{
			$this->error = $e->getMessage();
		}
	}
	
	public function query($query)
	{
	    $this->stmt = $this->dbh->prepare($query);
	}
	
	public function bind($param, $value, $type = null)
	{
		if (is_null($type))
		{
			switch(true)
			{
				case is_int($value):
					$type = PDO::PARAM_INT;
					break;
				
				case is_bool($value):
					$type = PDO::PARAM_BOOL;
					break;
					
				case is_null($value):
					$type = PDO::PARAM_NULL;
					break;
					
				default:
					$type = PDO::PARAM_STR;
			}
		}
		$this->stmt->bindValue($param, $value, $type);
	}
	
	public function execute()
	{
		return $this->stmt->execute();
	}
	
	public function resultSet()
	{
	    $this->execute();
	    return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
	}
	
	public function single()
	{
		$this->execute();
		return $this->stmt->fetch(PDO::FETCH_ASSOC);
	}
	
	public function rowCount()
	{
		return $this->stmt->rowCount();
	}
	
	public function lastInsertId()
	{
		return $this->dbh->lastInsertId();
	}
	
	public function beginTransaction()
	{
		return $this->dbh->beginTransaction();
	}
	
	public function endTransaction()
	{
		return $this->dbh->commit();
	}
	
	public function cancelTransaction()
	{
		return $this->dbh->rollBack();
	}
	
	public function debugDumpParams()
	{
		return $this->stmt->debugDumpParams();
	}
	
	public function sqlCount($table, $condition='', $value='', $operator='=')
	{
		if (!empty($condition) && !empty($value))
		{
			// Check if the condition and value have been given as an array
			if (is_array($condition) && is_array($value))
			{
			// Compare the amount of keys in both arrays
				if (!count($condition) == count($value))
				{
					// Throw an exception if the comparison returns false
					throw new ErrorHandler('Condition and Value arrays must match in size!');
				}
				else
				{
					// Count the amount of keys given
					// We use the condition array, but the value array could have been used as well
					$condition_count = count($condition);
					
					// Compare the operator count with those of the conditions
					// If the operator is an array
					if (is_array($operator) && !count($operator) == $condition_count)
					{
						// Throw an exception if the comparison returns false
						throw new ErrorHandler('Operator array count must match with that of conditions and values');
					}
					else
					{
						// Initiate the query
						$query = "SELECT COUNT(*) AS amount FROM ".$table." ";
						
						// Prepare looping values
						$i_condition 	= 0;
						$i_value		= 0;
						$i_operator		= 0;
						
						// Loop all conditions into a new array
						foreach ($condition as $key)
						{
							$a_condition[$i_condition] = $key;
							$i_condition++;
						}
						
						// Loop all values into a new array
						foreach ($value as $key)
						{
							$a_value[$i_value] = $key;
							$i_value++;
						}
						
						// Loop all operators into a new array
						// if the operator is an array
						if (is_array($operator))
						{
							foreach ($operator as $key)
							{
								$a_operator[$i_operator] = $key;
								$i_operator++;
							}
						}
						
						// Now loop all arrays and finish our query
						for ($i = 0; $i < $i_condition; $i++)
						{
							// Decide what the actual operator will be
							$this_operator = (is_array($operator)) ? $a_operator[$i] : $operator;
							
							if ($i == 0)
							{
								$query .= "WHERE ".$a_condition[$i]." ".$this_operator." :".$a_value[$i]."";
							}
							else
							{
								$query .= "AND ".$a_condition[$i]." ".$this_operator." :".$a_value[$i]."";
							} // End: if
						} // End: for
					} // End: if
				} //End: if
			}
			else
			{
				$query = "SELECT COUNT(*) AS amount FROM ".$table." WHERE ".$condition." ".$operator." :".$condition."";
				$bind_value = true;
				$bind_array = false;
			} // End: if     
		}
		else
		{
			$query = "SELECT COUNT(*) AS amount FROM ".$table;
			$bind_value = false;
		} // End: if 
		$this->query($query);
		if ($bind_value)
		{
			if ($bind_array)
			{
				foreach($a_condition as $key => $value)
				{
					$this->bind(':'.$value, $a_value[$key]);
				}
			}
			else
			{
				$this->bind(':'.$condition, $value);
			}
		}
		$row = $this->single();
		return $row['amount'];
	}
	
	public function sqlSelect($table, $fields = '', $where_con = '', $where_val = '', $limit = 0, $offset = 0, $order_by = '', $order_dir = '')
    {
    	$query_fields 	= '';
    	$query_where 	= '';
    	$query_limit 	= '';
    	$query_order 	= '';
    	$i_rows = 0;
    	
    	// Set the fields
    	if (is_array($fields))
    	{
  			$query_fields .= implode(',', $fields);
    	}
    	elseif (!empty($fields))
    	{
    		$query_fields .= $fields;
    	}
    	else
    	{
    		$query_fields .= '*';
    	}
    	
    	if (is_array($where_con))
    	{
    		$i_where_array = 0;
    		foreach ($where_con as $condition => $value)
    		{
    			if ($i_where_array == 0)
    			{
    				$query_where .= "WHERE ".$condition." = '".$value."'";
    			}
    			else
    			{
    				$query_where .= "AND ".$condition." = '".$value."'";
    			}
    			$i_where_array++;
    		}
    		
    	}
    	elseif (!empty($where_con) && !empty($where_val))
    	{
    		$query_where .= "WHERE ".$where_con." = '".$where_val."'";
    	}
    	
    	$query = 	'
					SELECT		'.$query_fields.'
					FROM		'.$table.'
					'.$query_where.'
					'.$query_order.'
					'.$query_limit.'
					';
		//echo $query;
		$sql = parent::sql_query($query);
		if (!$sql)
		{
			throw new ErrorHandler('There was an error while retrieivng the data from the database');
		}
		$array = array();
		while ($row = parent::sql_fetch_assoc($sql))
		{
			foreach ($row as $key => $value)
			{
				$array[$i_rows][$key] = $value;
			}
			$i_rows++;
		}
		
    	return $array;
    }
    
    public function sqlSelectRow($table, $fields = '', $where_con = '', $where_val = '', $limit = 0, $offset = 0, $order_by = '', $order_dir = '')
    {
    	$query_fields 	= '';
    	$query_where 	= '';
    	$query_limit 	= '';
    	$query_order 	= '';
    	$i_rows = 0;
    	
    	// Set the fields
    	if (is_array($fields))
    	{
  			$query_fields .= implode(',', $fields);
    	}
    	elseif (!empty($fields))
    	{
    		$query_fields .= $fields;
    	}
    	else
    	{
    		$query_fields .= '*';
    	}
    	
    	if (is_array($where_con))
    	{
    		$i_where_array = 0;
    		foreach ($where_con as $condition => $value)
    		{
    			if ($i_where_array == 0)
    			{
    				$query_where .= "WHERE ".$condition." = :".$condition;
    			}
    			else
    			{
    				$query_where .= "AND ".$condition." = :".$condition;
    			}
    			$i_where_array++;
    		}
    		
    	}
    	elseif (!empty($where_con) && !empty($where_val))
    	{
    		$query_where .= "WHERE ".$where_con." = '".$where_val."'";
    	}
    	
    	$query = 	'
					SELECT		'.$query_fields.'
					FROM		'.$table.'
					'.$query_where.'
					'.$query_order.'
					'.$query_limit.'
					';
		$sql = parent::sql_query($query);
		if (!$sql)
		{
			throw new ErrorHandler('There was an error while retrieivng the data from the database');
		}
		$row = parent::sql_fetch_assoc($sql);		
    	return $row;
    }
	
	public function sqlInsert($table, $data, $prefix='')
	{
		$list_fields = "";
    	$list_values = "";
    	$list_prefix = (!$prefix == '') ? $prefix : '';
    	foreach ($data as $key => $value)
    	{  
    		$list_fields .= "".$list_prefix.$key.", ";
    		$list_values .= ":".$key.", ";
    	}
    	$x_fields = strlen($list_fields);
    	$x_values = strlen($list_values);
    	
    	// Remove the last comma and space
    	$fields = substr($list_fields, 0, ($x_fields-2));
    	$values = substr($list_values, 0, ($x_values-2));
    	
    	// Start the transaction
    	$this->beginTransaction();
    	
    	// Build the query
    	$query	=	"
    				INSERT INTO		" . $table . "
    				(" . $fields . ")
    				VALUES
    				(" . $values . ")
    				";
		$this->query($query);
		
		// Bind all data
		foreach ($data as $key => $value)
		{
			$this->bind(':'.$key, $value);
		}
		
		//Execute the query
		$this->execute();
		
		// Define the insert ID before ending the transaction
		$this->insert_id[] = $this->lastInsertId();
		
		// End the transaction
		$this->endTransaction();
		
		// Return the generated ID
		return true;
	}
	
	public function sqlUpdate($table, array $data, $where_condition, $where_value, $prefix='')
	{
		// Check if there is even something to update
    	//if ($this->sqlCount($table, $where_condition, $where_value) >= '1')
	    //{
		   	// Initiate the data
		   	$list_data = '';
		   	
		   	// Check if a prefix needs to be used
		   	$list_prefix = (!$prefix == '') ? $prefix : '';
		   	
		   	// Loop all values together
		   	foreach ($data as $key => $value)
		   	{
		   		$list_data .= "".$list_prefix.$key." = :".$key.", ";
		   	}
		   	
		   	// Get the stringlength of the value loop
		   	$x_data = strlen($list_data);
		   	
		   	// Remove the last comma and space
		   	$values = substr($list_data, 0, ($x_data-2));
		   	
		   	// Start the transaction
    		$this->beginTransaction();
		   	
		   	// Build
		   	$query	=	"
		   				UPDATE		" . $table . "
						SET			" . $values . "
						WHERE		" . $where_condition . " = :" . $where_condition . "
		   				";
		   	$this->query($query);
			
			// Bind the where value
			$this->bind(':'.$where_condition, $where_value);
			
			// Bind all data
			foreach ($data as $key => $value)
			{
				$this->bind(':'.$key, $value);
			}
			
			//Execute the query
			$this->execute();
			
			// End the transaction
			$this->endTransaction();
			
			return true;
   		/*}
	    else
	    {
	    	return false;
	    }*/
	}
	
	public function sqlDelete($table, $where_condition, $where_value)
	{
		// Start the transaction
		$this->beginTransaction();
		
    	// Build the query
	    $query	=	"
	    			DELETE FROM	" . $table . "
					WHERE		" . $where_condition . " = :" . $where_condition . "
	    			";
	    $this->query($query);   
	    
	    // Bind data
	    $this->bind(':' . $where_condition, $where_value);
	    
	    // Execute the query
	    $this->execute();
	    
	    // End transaction
	    $this->endTransaction();
	    
    	return true;
	}
}

?>